// File Name: rs485_logic.c
// Author: kukukukuku~
// Date: 2024-10-23

#include "./RS485/inc/rs485_logic.h"
#include "apm32f00x_gpio.h"
#include "apm32f00x_usart.h"

/**
 * @brief   RS485计算CRC16
 * @param   data:       数据源
 * @param   dataLen:    数据长度
 * @retval  计算结果
 * @note    None
*/
uint16_t rs485_crc16_calc(uint8_t const * const data, uint16_t dataLen)
{
    uint16_t crcInit = 0xFFFF;
    uint16_t crcPoly = 0xA001;
    uint16_t crcVal = crcInit;
    
    if(data == NULL || dataLen == 0)
        return 0;

    for(uint16_t i = 0; i < dataLen; i++)
    {
        crcVal ^= data[i];
        
        for(uint8_t j = 0; j < 8; j++)
        {
            crcVal & 0x0001 ?\
            (crcVal = (crcVal >> 1) ^ crcPoly) :\
            (crcVal >>= 1);
        }
    }

    return crcVal;
}


/**
 * @brief   RS485发送数据
 * @param   data:       数据源
 * @param   dataLen:    数据长度
 * @retval  None
 * @note    None
*/
void rs485_send_data(uint8_t const * const data, const uint16_t dataLen)
{
    if(data == NULL || dataLen == 0)
        return;
    
    RS485_USART->CTRL2_B.RXEN = 0;
    RS485_USART->CTRL2_B.TXEN = 1;
    RS485_MODE_SEND;
    
    for(uint16_t i = 0; i < dataLen; i++)
    {
        while(!USART_ReadStatusFlag(RS485_USART, USART_FLAG_TXC));
        USART_TxData8(RS485_USART, data[i]);
    }
    
    while(!USART_ReadStatusFlag(RS485_USART, USART_FLAG_TXC));
    
    RS485_USART->CTRL2_B.RXEN = 1;
    RS485_USART->CTRL2_B.TXEN = 0;
    RS485_MODE_RECEIVE;
}
